package com.ruoyi.mes.service.impl;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.mes.domain.*;
import com.ruoyi.mes.mapper.*;
import com.ruoyi.mes.utils.*;
import com.ruoyi.mes.vo.plan.TaskCartVo;
import com.ruoyi.mes.vo.product.BomMtrVo;
import com.ruoyi.mes.vo.product.ProceVo;
import com.ruoyi.mes.vo.qualityinspection.QualityInspectionVo;
import com.ruoyi.mes.vo.wksp.RptVo;
//import javafx.concurrent.Task;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.ruoyi.mes.service.ITaskCartService;
import org.springframework.transaction.annotation.Transactional;

/**
 * 车间任务卡Service业务层处理
 *
 * @author LongAndHao
 * @date 2023-04-04
 */
@Service
public class TaskCartServiceImpl implements ITaskCartService {
    @Autowired
    private ProInfoServiceImpl proInfoService;

    @Autowired
    private TaskCartMapper taskCartMapper;

    @Autowired
    private WkspTaskMapper wkspTaskMapper;

    @Autowired
    private ProgPlanDetailMapper progPlanDetailMapper;

    @Autowired
    private ProgPlanMapper progPlanMapper;

    @Autowired
    private FinishInhouMapper finishInhouMapper;

    @Autowired
    private LocatorInfoMapper locatorInfoMapper;
    @Autowired
    private HouInfoMapper houInfoMapper;


    /**
     * 查询车间任务卡
     *
     * @param taskCardId 车间任务卡主键
     * @return 车间任务卡
     */
    @Override
    public TaskCart selectTaskCartByTaskCardId(Long taskCardId) {
        return taskCartMapper.selectTaskCartByTaskCardId(taskCardId);
    }

    /**
     * 查询车间任务卡列表
     *
     * @param taskCart 车间任务卡
     * @return 车间任务卡
     */
    @Override
    public List<TaskCart> selectTaskCartList(TaskCart taskCart) {
        return taskCartMapper.selectTaskCartList(taskCart);
    }

    /**
     * 新增车间任务卡
     *
     * @param taskCart 车间任务卡
     * @return 结果
     */
    @Override
    public int insertTaskCart(TaskCart taskCart) {
        taskCart.setCreateTime(DateUtils.getNowDate());
        return taskCartMapper.insertTaskCart(taskCart);
    }

    /**
     * 修改车间任务卡
     *
     * @param taskCart 车间任务卡
     * @return 结果
     */
    @Override
    public int updateTaskCart(TaskCart taskCart) {
        taskCart.setUpdateTime(DateUtils.getNowDate());
        return taskCartMapper.updateTaskCart(taskCart);
    }

    /**
     * 批量删除车间任务卡
     *
     * @param taskCardIds 需要删除的车间任务卡主键
     * @return 结果
     */
    @Override
    public int deleteTaskCartByTaskCardIds(Long[] taskCardIds) {
        return taskCartMapper.deleteTaskCartByTaskCardIds(taskCardIds);
    }

    /**
     * 删除车间任务卡信息
     *
     * @param taskCardId 车间任务卡主键
     * @return 结果
     */
    @Override
    public int deleteTaskCartByTaskCardId(Long taskCardId) {
        return taskCartMapper.deleteTaskCartByTaskCardId(taskCardId);
    }


    /**
     * 查 - 任务卡详情
     *
     * @param id 任务卡id
     * @return
     */
    @Override
    public AjaxResult getDetail(Long id) {
        TaskCart taskCart = taskCartMapper.selectTaskCartByTaskCardId(id);
        TaskCartVo taskCartVo = new TaskCartVo();
        taskCartVo.setTakCardCode(taskCart.getTakCardCode());

        List<TaskCart> taskCarts = taskCartMapper.selectTaskCartByCode(taskCart.getTakCardCode());
        taskCartVo.setTaskCartPlanQuantity((long) taskCarts.size());

        //查询车间任务
        WkspTask wkspTask = wkspTaskMapper.selectWkspTaskById(taskCart.getWkspTaskId());
        taskCartVo.setWkspCode(wkspTask.getWkspCode());
        taskCartVo.setWkspTaskProductionSchedule((float) wkspTask.getWkspReadyQuantity() / wkspTask.getWkspPlanQuantity() * 100);
        //查询产品
        ProInfo proInfo = proInfoService.selectProInfoById(wkspTask.getProId());
        taskCartVo.setProCode(proInfo.getProCode());
        taskCartVo.setProName(proInfo.getProName());
        //查询Bom
        BomMtrVo bomMtrVo = proInfoService.getBomAndMtrByProId(wkspTask.getProId()).getData();
        taskCartVo.setBomMtrVo(bomMtrVo);
        //查询产品订单编码
        ProgPlanDetail progPlanDetail = progPlanDetailMapper.selectProgPlanDetailById(wkspTask.getProgDetailId());
        ProgPlan progPlan = progPlanMapper.selectProgPlanById(progPlanDetail.getProgId());
        taskCartVo.setOrderNumber(progPlan.getOrderNumber());

        return AjaxResult.success("查询成功!", taskCartVo);
    }


    /**
     * 查 - 已排序的工序
     *
     * @param id 任务卡id
     * @return
     */
    @Override
    public AjaxResult sorted(Long id) {
        TaskCart taskCart = taskCartMapper.selectTaskCartByTaskCardId(id);

        //查找工序
        WkspTask wkspTask = wkspTaskMapper.selectWkspTaskById(taskCart.getWkspTaskId());
        List<ProceInfo> proceInfos = proInfoService.getProTec(wkspTask.getProId()).getData().getProceInfos();
        proceInfos.sort(Comparator.comparing(ProceInfo::getProceSeque));//根据工序顺序排序

        //处理返回
        List<ProceVo> list = new ArrayList<>();
        for (ProceInfo proceInfo : proceInfos) {
            ProceVo proceVo = new ProceVo();
            BeanUtils.copyProperties(proceInfo, proceVo);
            list.add(proceVo);
        }

        return AjaxResult.success("查询成功!", list);
    }


    /**
     * 报工
     *
     * @param rptVo
     * @return
     */
    @Override
    public AjaxResult report(RptVo rptVo) {
        TaskCart taskCart = taskCartMapper.selectTaskCartByTaskCardId(rptVo.getId());
        WkspTask wkspTask = wkspTaskMapper.selectWkspTaskById(taskCart.getWkspTaskId());

        // 获取所有与任务卡相关的任务卡（工序）
        List<TaskCart> taskCarts = taskCartMapper.selectTaskCartByTaskCardCode(taskCart.getTakCardCode(), 0, Integer.MAX_VALUE); // 获取所有工序任务卡

        // 固定的工序顺序：四轴机械臂 -> 小车行进 -> 打标机 -> 小车行进 -> 六轴机械臂 -> 小车行进
        for (int i = 0; i < taskCarts.size(); i++) {
            TaskCart currentTask = taskCarts.get(i);

            // 检查前一工序是否完成
            if (i > 0) {
                TaskCart previousTask = taskCarts.get(i - 1);
                if (previousTask.getTaskReadyRptNum() < previousTask.getTaskNeedRptNum()) {
                    return AjaxResult.error("前一步工序未完成!");
                }
            }

            // 执行当前工序的自动化操作
            switch (currentTask.getRptProceSeque().intValue()) {
                case 1:
                    // 四轴机械臂工作
                    FourMechanicalArmUtils.FourMechanicalArmMove(currentTask.getTakCardCode());
                    break;
                case 2:
                    // 小车行进
                    AgvUtils.dispatchAgv();
                    break;
                case 3:
                    // 打标机工作
                    MarkingMachineUtils.MarkingMachineMarkingWord(currentTask.getTakCardCode());
                    break;
                case 4:
                    // 小车行进
                    AgvUtils.dispatchAgv();
                    break;
                case 5:
                    // 六轴机械臂工作
                    SixMechanicalArmUtils.SixMechanicalArmGrab(currentTask.getTakCardCode());
                    break;
                case 6:
                    // 小车行进
                    AgvUtils.dispatchAgv();
                    break;
                default:
                    return AjaxResult.error("未知工序!");
            }

            // 更新当前工序任务卡的报工状态
            currentTask.setRptProceSeque(currentTask.getRptProceSeque());  // 保持工序顺序
            currentTask.setTaskReadyRptNum(currentTask.getTaskReadyRptNum() + 1);
            taskCartMapper.updateTaskCart(currentTask);
        }

// 所有工序完成后执行质检操作
        try {
            QualityInspectionVo qualityInspectionVo = QualityInspectionUtils.qualityInspection();
            if (!qualityInspectionVo.getIs_pass()) {
                return AjaxResult.error("质检未通过!");
            }
        } catch (IOException e) {
            // 返回错误信息
            return AjaxResult.error("质检过程出错: " + e.getMessage());
        }

        // 质检通过后，执行入库操作
        // 创建入库单
        FinishInhou finishInhou = new FinishInhou();
        finishInhou.setWkspTaskId(wkspTask.getId());
        finishInhou.setWkspCode(wkspTask.getWkspCode());
        finishInhou.setProId(wkspTask.getProId());
        finishInhou.setInhouName(SecurityUtils.getLoginUser().getUser().getNickName());
        finishInhou.setInhouTime(DateUtils.getNowDate());
        finishInhou.setInhouQuantity(wkspTask.getWkspReadyQuantity());
        finishInhou.setStatus(0L); // 默认未入库
        finishInhou.setRemark("自动报工");
        finishInhouMapper.insertFinishInhou(finishInhou);

        // 执行入库操作
        ScheduledExecutorService executorService = Executors.newSingleThreadScheduledExecutor();
        executorService.schedule(() -> {
            // 等待24秒后执行以下代码
            LongMenUtils.LongMenPutWithLocator(18L);

            // 更新库存信息和库位容量
            LocatorInfo locatorInfo = locatorInfoMapper.selectLocatorInfoById(18L);
            locatorInfo.setRemainCapacity(locatorInfo.getRemainCapacity() - 1);

            HouInfo houInfo = houInfoMapper.selectHouInfoByHouId(locatorInfo.getHouId());
            houInfo.setHouRemainCapacity(houInfo.getHouRemainCapacity() - 1);

            // 完工入库信息更新
            finishInhou.setStatus(1L); // 设置为已入库
            houInfoMapper.updateHouInfo(houInfo);
            locatorInfoMapper.updateLocatorInfo(locatorInfo);
            finishInhouMapper.updateFinishInhou(finishInhou); // 更新入库单状态
        }, 24, TimeUnit.SECONDS);

        // 等待一段时间后再派发AGV
        try {
            Thread.sleep(1000 * 27); // 模拟延迟，实际根据需要调整
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
        AgvUtils.dispatchAgv();  // 完成后派发AGV

        // 更新车间任务状态
        wkspTask.setWkspReadyQuantity((long) taskCarts.size() + wkspTask.getWkspReadyQuantity());
        wkspTaskMapper.updateWkspTask(wkspTask);

        if (wkspTask.getWkspPlanQuantity().longValue() == wkspTask.getWkspReadyQuantity().longValue()) {
            wkspTask.setOperationStatus(2L);  // 任务完成
            wkspTaskMapper.updateWkspTask(wkspTask);
        }

        // 任务卡所有工序完成后返回
        return AjaxResult.success("报工成功!");
    }



    /**
     * 查 - 任务卡分页 - 任务卡编码不重复
     *
     * @param taskCart
     * @return
     */
    @Override
    public List<TaskCart> taskCardList(TaskCart taskCart) {
        List<TaskCart> taskCarts = taskCartMapper.taskCardList(taskCart);
        if (taskCarts.size() != 0) {

            for (TaskCart cart : taskCarts) {
                boolean flag = false;

                //计算需报工次数，已报工次数总和
                List<TaskCart> list = taskCartMapper.selectTaskCartByCode(cart.getTakCardCode());
                int needCount = 0, readyCount = 0;
                for (TaskCart cart1 : list) {
                    needCount += cart1.getTaskNeedRptNum();
                    readyCount += cart1.getTaskReadyRptNum();
                    if (cart1.getStatus() == 1) {
                        flag = true;
                    }

                }

                WkspTask wkspTask = wkspTaskMapper.selectWkspTaskById(cart.getWkspTaskId());
                cart.setWkspCode(wkspTask.getWkspCode());
                cart.setTaskCartProductionSchedule((float) readyCount / needCount * 100);
                if (flag) {
                    cart.setStatus(1L);
                }
                ProInfo proInfo = proInfoService.selectProInfoById(wkspTask.getProId());
                cart.setProCode(proInfo.getProCode());
                cart.setProName(proInfo.getProName());


            }
        }
        return taskCarts;
    }

    /**
     * 查 - 可报工数量
     *
     * @param id         任务卡id
     * @param proceSeque 报工顺序
     * @return
     */
    @Override
    public AjaxResult getTransferredQuantity(Long id, Long proceSeque) {
        TaskCart taskCart = taskCartMapper.selectTaskCartByTaskCardId(id);
        List<TaskCart> taskCarts = taskCartMapper.selectTaskCartByTaskCardCode(taskCart.getTakCardCode(), proceSeque - 1, -1);
        return AjaxResult.success("可报工数量", taskCarts.size());
    }
}
